package com.example.wishstar.repository;

import android.os.AsyncTask;
import android.util.Log;

import androidx.lifecycle.LiveData;

import com.example.wishstar.api.Api;
import com.example.wishstar.db.UserDao;
import com.example.wishstar.model.CommonDate;
import com.example.wishstar.model.Habit;
import com.example.wishstar.model.HabitWish;
import com.example.wishstar.model.UpdateHabit;
import com.example.wishstar.model.UpdateWish;
import com.example.wishstar.model.Wish;
import com.example.wishstar.utils.ApiResponse;
import com.google.gson.JsonObject;

import java.time.LocalDate;
import java.util.List;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class HabitWishRepository {
    private String TAG = "HabitWishRepository";
    private UserDao userDao;
    private Api api;

    public HabitWishRepository(UserDao userDao, Api api) {
        this.userDao = userDao;
        this.api = api;
    }

    public LiveData<List<Habit>> getHabits(int userId) {
        refresh(userId);
        return userDao.getHabitByuserId(userId);
    }

    public LiveData<List<Wish>> getWishs(int userId) {
        refresh(userId);
        return userDao.getWishByuserId(userId);
    }

    public void refresh(Integer userId) {


        api.getHabitWish(userId).enqueue(new Callback<ApiResponse<HabitWish>>() {
            @Override
            public void onResponse(Call<ApiResponse<HabitWish>> call, Response<ApiResponse<HabitWish>> response) {
                if(response.body() != null && response.body().code == 200) {
                    deleteHabitByUserId(userId);
                    deleteWishByUserId(userId);
                    Log.e(TAG, "refresh->response" + response.body());
                    insertHabit(userId, response.body().getData().getHabitVOList());
                    insertWish(userId, response.body().getData().getWishVOList());
                }
            }

            @Override
            public void onFailure(Call<ApiResponse<HabitWish>> call, Throwable t) {
                Log.e(TAG, "refresh()->onFailure()");
            }
        });
    }

    public void updateHabit(UpdateHabit updateHabit) {
        JsonObject fieldMap = new JsonObject();
        fieldMap.addProperty("habitDetails", updateHabit.habitDetails);
        fieldMap.addProperty("habitId", updateHabit.habitId);
        fieldMap.addProperty("state", updateHabit.state);
        api.updateHabit(RequestBody.create(MediaType.parse("application/json"), fieldMap.toString())).enqueue(new Callback<ApiResponse<Integer>>() {
            @Override
            public void onResponse(Call<ApiResponse<Integer>> call, Response<ApiResponse<Integer>> response) {
                Log.e(TAG, "updateHabit->onResponse");
                if (response.body() != null) {
                    if (response.body().code == 200) {
                        if (updateHabit.state == 2) {
                            deleteHabit(updateHabit.habitId);
                        }
                        Log.e(TAG, "updateHabit成功");
                    }
                }
            }

            @Override
            public void onFailure(Call<ApiResponse<Integer>> call, Throwable t) {
                Log.e(TAG, "updateHabit->onFailure");
            }
        });
    }

    public void updateWish(UpdateWish updateWish) {
        JsonObject fieldMap = new JsonObject();
        fieldMap.addProperty("wishId", updateWish.wishId);
        fieldMap.addProperty("wishDetails", updateWish.wishDetails);

        api.updateWish(RequestBody.create(MediaType.parse("application/json"), fieldMap.toString())).enqueue(new Callback<ApiResponse<Integer>>() {
            @Override
            public void onResponse(Call<ApiResponse<Integer>> call, Response<ApiResponse<Integer>> response) {
                Log.e(TAG, "updateWish->onResponse");
                if (response.body() != null) {
                    if (response.body().code == 200) {
                        deleteWish(updateWish.wishId);
                        Log.e(TAG, "updateWish成功");
                    }
                }
            }

            @Override
            public void onFailure(Call<ApiResponse<Integer>> call, Throwable t) {
                Log.e(TAG, "updateWish->onFailure");
            }
        });
    }

    public void deleteWishByWishId(int wishId) {
        api.deleteWish(wishId).enqueue(new Callback<ApiResponse<String>>() {
            @Override
            public void onResponse(Call<ApiResponse<String>> call, Response<ApiResponse<String>> response) {
                Log.e(TAG, "deleteWish()->onResponse()");
                if(response.body() != null && response.body().code == 200) {
                    deleteWish(wishId);
                }
            }

            @Override
            public void onFailure(Call<ApiResponse<String>> call, Throwable t) {
                Log.e(TAG, "deleteWish()->onFailure()");
            }
        });
    }

    public void deleteHabitByHabitId(int habitId) {
        api.deleteHabit(habitId).enqueue(new Callback<ApiResponse<String>>() {
            @Override
            public void onResponse(Call<ApiResponse<String>> call, Response<ApiResponse<String>> response) {
                Log.e(TAG, "deleteHabit()->onResponse()");
                if(response.body() != null && response.body().code == 200) {
                    deleteHabit(habitId);
                }
            }

            @Override
            public void onFailure(Call<ApiResponse<String>> call, Throwable t) {
                Log.e(TAG, "deleteHabit()->onFailure()");
            }
        });
    }

    private void deleteHabit(int habitId) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                userDao.deleteHabitByHabitId(habitId);
            }
        });
    }

    private void deleteWish(int wishId) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                userDao.deleteWishByWishId(wishId);
            }
        });
    }

    public void delayWish(int wishId, CommonDate commonDate) {
        JsonObject fieldMap = new JsonObject();
        fieldMap.addProperty("wishId", wishId);
        LocalDate date = LocalDate.of(Integer.valueOf(commonDate.year), Integer.valueOf(commonDate.month), Integer.valueOf(commonDate.day));
        fieldMap.addProperty("newWishDate", date.toString());

        api.delayWish(RequestBody.create(MediaType.parse("application/json"), fieldMap.toString())).enqueue(new Callback<ApiResponse<Integer>>() {
            @Override
            public void onResponse(Call<ApiResponse<Integer>> call, Response<ApiResponse<Integer>> response) {
                Log.e(TAG, "delayWish->onResponse");
                if (response.body() != null) {
                    if (response.body().code == 200) {
                        Log.e(TAG, "delayWish成功");
                    }
                }
            }

            @Override
            public void onFailure(Call<ApiResponse<Integer>> call, Throwable t) {
                Log.e(TAG, "delayWish->onFailure");
            }
        });
    }

    public void insertWish(int userId, List<Wish> wishList) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < wishList.size(); ++i) {
                    Log.e(TAG, wishList.get(i).toString());

                    Wish wish = wishList.get(i);
                    wish.userId = userId;
                    wish.conutdownDaysString = "倒计时" + wish.conutdownDays + "天";

                    userDao.insertWish(wish);
                }
            }
        });
    }

    public void insertHabit(int userId, List<Habit> habitList) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < habitList.size(); ++i) {
                    Log.e(TAG, habitList.get(i).toString());

                    Habit habit = habitList.get(i);
                    habit.userId = userId;
                    habit.dayNumString = "坚持" + habit.dayNum + "天";

                    userDao.insertHabit(habit);
                }
            }
        });
    }

    public void deleteHabitByUserId(int userId) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                userDao.deleteHabitByUserId(userId);
            }
        });
    }

    public void deleteWishByUserId(int userId) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                userDao.deleteWishByUserId(userId);
            }
        });
    }
}
